import isElectron from 'is-electron';
import http from 'http';
import fs from 'fs';
import { Server as SocketServer } from 'socket.io';
import pathManager from './PathManager.js';
import { spawn } from 'child_process';
import Jimp from 'jimp';

function base64ToBMP(base64String, outputFile, callback) {
    try {
        // 将 Base64 解码为 Buffer
        const buffer = Buffer.from(base64String, 'base64');

        // 读取 Buffer 并转换为 BMP
        Jimp.read(buffer, (err, image) => {
            if (err) {
                return callback(new Error(`Base64 转 BMP 失败: ${err.message}`));
            }

            // 写入 BMP 文件
            image.write(outputFile, (err) => {
                if (err) {
                    return callback(new Error(`保存 BMP 失败: ${err.message}`));
                }

                callback(null, `BMP 文件已保存至: ${outputFile}`);
            });
        });
    } catch (error) {
        return callback(new Error(`Base64 转 BMP 失败: ${error.message}`));
    }
}

function readSVGSync(filePath) {
    try {
        return fs.readFileSync(filePath, 'utf8'); // 以 UTF-8 读取文件内容
    } catch (error) {
        console.error(`读取文件失败: ${error.message}`);
        return null;
    }
}

const httpServer = http.createServer();
const socketServer = new SocketServer(httpServer, {
    // 从 Socket.IO v3 开始，需要显式启用跨域资源共享(CORS) 允许所有链接
    cors: { origin: '*' }
});

const potraceProcess = ({
    potracePath,
    filePathInput,
    filePathOutputPotrace,
    potraceArgs,
    ack
}) => {
    const exePath = potracePath;
    const args = [filePathInput, '-s', '-o', filePathOutputPotrace, ...potraceArgs];
    console.log('potrace: ' + JSON.stringify(args, null, 2));

    const childProcess = spawn(exePath, args);
    childProcess.stdout.on('data', (data) => {
        console.log(`potrace: stdout: ${data}`);
    });
    childProcess.stderr.on('data', (data) => {
        console.error(`potrace: stderr: ${data}`);
    });
    childProcess.on('error', (err) => {
        console.error(`potrace: 子进程启动失败: ${err}`);
    });
    childProcess.on('close', (code) => {
        console.log(`potrace: 子进程退出，退出码: ${code}`);
        if (code === 0) {
            // 读取 svg 得到 string
            const svgStr = readSVGSync(filePathOutputPotrace);
            ack({ success: true, msg: null, svgStr });
        } else {
            ack({ success: false, msg: 'potrace code: ' + code, svgStr: '' });
        }
    });
};

socketServer.on('connection', (socket) => {
    console.log('socket -> connect');
    socket.on('disconnect', () => {
        console.log('socket -> disconnect');
    });

    // ack({success: true/false, msg: "xx", svgStr: "xx"})
    socket.on('bitmap2svg', (args, ack) => {
        const { imgBase64, potraceArgs, mkbitmapArgs, mkbitmapEnable } = args;

        console.log('potraceArgs: ' + JSON.stringify(potraceArgs, null, 2));
        console.log('mkbitmapArgs: ' + JSON.stringify(mkbitmapArgs, null, 2));
        console.log('mkbitmapEnable: ' + mkbitmapEnable);

        const { tempDirPath, potracePath, mkbitmapPath } = pathManager;

        // imgBase64 => input.bmp => [mkbitmap] => mkbitmap.bmp => [potrace] => potrace.svg
        const filePathInput = tempDirPath + '/input.bmp'; // web 传过来的图片（转为 bmp）
        const filePathOutputMkbitmap = tempDirPath + '/mkbitmap.pbm';
        const filePathOutputPotrace = tempDirPath + '/potrace.svg'; //

        // 1. imgBase64 => input.bmp
        base64ToBMP(imgBase64, filePathInput, (err) => {
            if (err) {
                ack({ success: false, msg: err.message, svgStr: null });
                return;
            }

            console.log('ok: imgBase64 => input.bmp');

            if (mkbitmapEnable) {
                {
                    const exePath = mkbitmapPath;
                    const args = [filePathInput, '-o', filePathOutputMkbitmap, ...mkbitmapArgs];
                    console.log('mkbitmap: ' + JSON.stringify(args, null, 2));

                    const childProcess = spawn(exePath, args);
                    childProcess.stdout.on('data', (data) => {
                        console.log(`mkbitmap: stdout: ${data}`);
                    });
                    childProcess.stderr.on('data', (data) => {
                        console.error(`mkbitmap: stderr: ${data}`);
                    });
                    childProcess.on('error', (err) => {
                        console.error(`mkbitmap: 子进程启动失败: ${err}`);
                    });
                    childProcess.on('close', (code) => {
                        console.log(`mkbitmap: 子进程退出，退出码: ${code}`);
                        if (code === 0) {
                            potraceProcess({
                                potracePath,
                                filePathInput: filePathOutputMkbitmap,
                                filePathOutputPotrace,
                                potraceArgs,
                                ack
                            });
                        } else {
                            ack({ success: false, msg: 'mkbitmap code: ' + code, svgStr: '' });
                        }
                    });
                }
            } else {
                potraceProcess({
                    potracePath,
                    filePathInput,
                    filePathOutputPotrace,
                    potraceArgs,
                    ack
                });
            }
        });
    });
});

if (isElectron()) {
    // electron 环境下:
    // 1. 动态获取可用端口
    // 2. serverAddress 挂在 window 下，供前端获取
    // 说明：electron 环境下，web 和 server 在同一个沙盒，server 可以访问 window，可以通过 window 传递数据
    httpServer.on('listening', () => {
        //http://nodejs.cn/api/net.html#net_class_net_server
        const { port, address } = httpServer.address();
        window.serverAddress = `http://localhost:${port}`;
        console.log('address: ' + address);
        console.log('server run on: ' + window.serverAddress);
    });
    httpServer.listen(0);
} else {
    // dev 环境下，固定使用：http://localhost:9000
    const port = 9000;
    httpServer.listen(port);
    console.log('server run on: ' + `http://localhost:${port}`);
}
